var React = require('react');
var Draggable = require('../../utils/Draggable');
var DOMUtil = require('../../utils/DOMUtil');

var Node = React.createClass({
	displayName:'Node',
	getInitialState:function(){
		this._links = {};
		this._nodes = {};
		this.props.draggable = (this.props.draggable==undefined) ? true: this.props.draggable;
		return {
			highLight: false
		}
	},
	getCenterXY: function (){
		var _position =  DOMUtil.getPosition(this.getDOMNode());
	    var _halfWidth = _position.width / 2.0,
	        _halfHeight = _position.height / 2.0,
	        _x = 0, _y = 0;

		if(!this.props.draggable){
			_x = _position.x - this._parentPosition.x + _halfWidth;
			_y = _position.y - this._parentPosition.y + _halfHeight;
		} else {
			_x = this._x + _halfWidth;
	        _y = this._y + _halfHeight;
			if(this.props.parent){
				_x = _x + this.props.parent._x;
				_y = _y + this.props.parent._y;
			}
		}

	    return {
	        x: _x,
	        y: _y
	    };
	},
    setLink: function (id, link){
        this._links[id] = link;
    },
    getLink: function (id){
        return this._links[id];
    },
    deleteLink: function (id){
        this._links[id] = null;
        delete this._links[id];
    },
	setNode: function (key, node){
		this._nodes[key] = node;
	},
	addNode: function (node){
		var _node = null,
			_key;

		if(node){
			_node = <Node {...node}/>;
			this._nodes[_node._id] = _node;
			React.render(_node, this.getDOMNode());
		}
	},
	componentDidMount:function(){
		var _source = this.getDOMNode(),
			_self = this;

		this._id = this.props.id;
		this._x = this.props.x||0;
		this._y = this.props.y||0;
		this._parentPosition = DOMUtil.getPosition(this.getDOMNode().parentNode);

		if(this.props.draggable){
			Draggable.init(_source, {
				start: [this.props.x, this.props.y],
				onDragStart: this.__onNodeDragStart,
				onDrag: this.__onNodeDrag,
				onDragEnd: this.__onNodeDragEnd
			});
		}

		DOMUtil.on(_source, 'mouseover', this.__onMouseOver);
		DOMUtil.on(_source, 'mouseout', this.__onMouseOut);

		this.props.onDidMount && this.props.onDidMount(this, this.props);
	},
	__onNodeDragStart: function (){
		var _dom = this.getDOMNode();
		this._oldZIndex = _dom.style.zIndex;
        _dom.style.zIndex = 10;
	},
	__onNodeDragEnd: function (){
        this.getDOMNode().style.zIndex = this._oldZIndex;
	},
	__onNodeDrag: function (x, y){
		this._x = x;
		this._y = y;
		this.__onLinkReset();
        this.__scanChild();
		this.onNodeDrag && this.onNodeDrag(x, y);
	},
	__onLinkReset: function () {
		var _links = this._links;
        for(var key in _links){
            _links[key].reset();
        }
	},
	__scanChild: function () {
		var _nodes = this._nodes;
        for(var key in _nodes){
            _nodes[key].__onLinkReset();
        }
	},
	__onClick: function (event){
		this.props.onClick && this.props.onClick(this.props, event);
	},
	__onMouseOver: function (event){
		for(var key in this._links){
			this._links[key].highLight(true);
		}
	},
	highLight: function (){
		this.setState({
			highLight: true
		});
	},
	__onMouseOut: function (event){
		for(var key in this._links){
			this._links[key].highLight(false);
		}
		this.setState({
			highLight: false
		});
	},
	render:function(){
		return (
			<div className={"graph-node " + (this.props.type||'type-node')} data-highlight={this.state.highLight} data-draggable={this.props.draggable} style={this.props.style} onClick={()=>this.__onClick}>
				{this.props.render && this.props.render(this, this.props)}
			</div>
		);
	}
});

module.exports = Node;
